package com.agileai.portal.portlets.simple;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletModeException;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.portlet.ProcessAction;
import javax.portlet.ReadOnlyException;
import javax.portlet.RenderMode;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.ValidatorException;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

import com.agileai.hotweb.common.StringTemplateLoader;
import com.agileai.portal.driver.Resource;
import com.agileai.portal.driver.common.PreferenceException;
import com.agileai.portal.driver.common.PreferencesHelper;
import com.agileai.portal.driver.common.PreferencesWrapper;
import com.agileai.portal.portlets.BaseMashupPortlet;
import com.agileai.portal.portlets.PortletCacheManager;
import com.agileai.util.StringUtil;

import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
/**
 * generated by miscdp
 */
public class Tempate8JsonMergePortlet extends BaseMashupPortlet {
	private static final String DefaultHeight = "400px";
	private static final String NewLine = "\r\n";
	private static final String DynamicParseMode = "D";
	
	private static final String getDefalutJsHandler(){
		StringBuffer result = new StringBuffer();
		result.append("function(divContainerId){").append(NewLine);
			
		result.append("}").append(NewLine);
		return result.toString();
	}
	
	@RenderMode(name = "view")
	public void view(RenderRequest request, RenderResponse response)
			throws PortletException, IOException {
		PortletPreferences preferences =  PreferencesHelper.getPublicPreference(request);
		String height = preferences.getValue("height", DefaultHeight);
		String jsHandler = preferences.getValue("jsHandler", null);
		String dataURL = preferences.getValue("dataURL", null);
		String parseMode = preferences.getValue("parseMode", DynamicParseMode);
		boolean isSetting = StringUtil.isNotNullNotEmpty(jsHandler) && StringUtil.isNotNullNotEmpty(dataURL);
		
		request.setAttribute("height",height);
		request.setAttribute("jsHandler", jsHandler);
		request.setAttribute("isSetting", String.valueOf(isSetting));
		request.setAttribute("portletId", request.getWindowID());
		request.setAttribute("parseMode",parseMode);
		super.doView(request, response);
	}

	@RenderMode(name = "edit")
	public void edit(RenderRequest request, RenderResponse response)
			throws PortletException, IOException {
		PortletPreferences preferences = PreferencesHelper.getPublicPreference(request);
		
		String height = preferences.getValue("height", DefaultHeight);
		String template = preferences.getValue("template", null);
		String jsHandler = preferences.getValue("jsHandler", getDefalutJsHandler());
		String dataURL = preferences.getValue("dataURL", null);
		String defaultVariableValues = preferences.getValue("defaultVariableValues", null);
		String isCache = preferences.getValue("isCache", defaultIsCache);
		String cacheMinutes = preferences.getValue("cacheMinutes", defaultCacheMinutes);
		String parseMode = preferences.getValue("parseMode", DynamicParseMode);
		
		request.setAttribute("height", height);
		request.setAttribute("template", template);
		request.setAttribute("jsHandler", jsHandler);
		request.setAttribute("dataURL", dataURL);
		request.setAttribute("defaultVariableValues", defaultVariableValues);
		request.setAttribute("isCache", isCache);
		request.setAttribute("parseMode", parseMode);
		request.setAttribute("cacheMinutes", cacheMinutes);
				
		super.doEdit(request, response);
	}

	@ProcessAction(name = "saveConfig")
	public void saveConfig(ActionRequest request, ActionResponse response)
			throws ReadOnlyException, PortletModeException, ValidatorException,
			IOException, PreferenceException {
		String height = request.getParameter("height");
		String template = request.getParameter("template");
		String jsHandler = request.getParameter("jsHandler");
		String parseMode = request.getParameter("parseMode");
		
		String dataURL = request.getParameter("dataURL");
		String defaultVariableValues = request.getParameter("defaultVariableValues");
		String isCache = request.getParameter("isCache");
		String cacheMinutes = request.getParameter("cacheMinutes");

		PreferencesWrapper preferWapper = new PreferencesWrapper();		
		preferWapper.setValue("height", height);
		preferWapper.setValue("template", template);
		preferWapper.setValue("jsHandler", jsHandler);
		preferWapper.setValue("parseMode", parseMode);
		
		preferWapper.setValue("defaultVariableValues", defaultVariableValues);
		preferWapper.setValue("dataURL", dataURL);
		preferWapper.setValue("isCache", isCache);
		preferWapper.setValue("cacheMinutes", cacheMinutes);
		
		PreferencesHelper.savePublicPreferences(request, preferWapper.getPreferences());	
		response.setPortletMode(PortletMode.VIEW);
	}
	
	@SuppressWarnings({ "rawtypes"})
	@Resource(id="getAjaxData")
	public void getAjaxData(ResourceRequest request, ResourceResponse response)
			throws PortletException, IOException {
		String ajaxData = "";
		String html = "";
		try {
			PortletPreferences preferences = PreferencesHelper.getPublicPreference(request);
			String cacheMinutes = (String)preferences.getValue("cacheMinutes",defaultCacheMinutes);
			String isCache = preferences.getValue("isCache", defaultIsCache);
			String dataURL = getDataURL(request);
			ajaxData = PortletCacheManager.getOnly().getCachedData(isCache, dataURL, cacheMinutes);
			
			String template = preferences.getValue("template", null);
			if (template != null){
				if (template.startsWith("http://")){
					template = this.retrieveTemplate(request, template);
				}
				
				String parseMode = preferences.getValue("parseMode", DynamicParseMode);
				if (DynamicParseMode.equals(parseMode)){
					html = mergeTempate8JsonData(ajaxData, template);					
				}else{
					HashMap map = this.buildVarMap(ajaxData);
					html = mergeTempate8JsonData(map, template);
				}
			}
			
		} catch (Exception e) {
			this.logger.error("获取取数据失败getAjaxData", e);
		}
		PrintWriter writer = response.getWriter();
		writer.print(html);
		writer.close();
	}
	
	@SuppressWarnings("rawtypes")
	private HashMap buildVarMap(String json){
		HashMap<String,String> map = new HashMap<String,String>();
		ObjectMapper mapper = new ObjectMapper();
		try {
			map = mapper.readValue(json, new TypeReference<HashMap<String,Object>>(){});
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}
	
	private String retrieveTemplate(PortletRequest request, String dataURL) {
		String result = "";
		try {
			int index = dataURL.lastIndexOf("=");
			String templateId = dataURL.substring(index+1,dataURL.length());
			result = PortletCacheManager.getOnly().getCachedData("Y",templateId,dataURL, "0");
		} catch (Exception e) {
			this.logger.error("retrieve template error ", e);
		}
		return result;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private String mergeTempate8JsonData(String ajaxData,String template){
		String result = null;
		try {
			StringWriter writer = new StringWriter();
			
			String encoding = "utf-8";
	    	Configuration cfg = new Configuration();
	    	cfg.setTemplateLoader(new StringTemplateLoader(template));  
	    	cfg.setEncoding(Locale.getDefault(), encoding);
	        cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
	    	Template temp = cfg.getTemplate("");
	    	temp.setEncoding(encoding);
	        Map root = new HashMap();
	        root.put("text",ajaxData);
	        temp.process(root, writer);
	        writer.flush();
			
			result = writer.toString();			
		} catch (Exception e) {
			e.printStackTrace();
			result = "";
		}
		return result;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private String mergeTempate8JsonData(HashMap map,String template){
		String result = null;
		try {
			StringWriter writer = new StringWriter();
			
			String encoding = "utf-8";
	    	Configuration cfg = new Configuration();
	    	cfg.setTemplateLoader(new StringTemplateLoader(template));  
	    	cfg.setEncoding(Locale.getDefault(), encoding);
	        cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
	    	Template temp = cfg.getTemplate("");
	    	temp.setEncoding(encoding);
			HashMap root = new HashMap();
			root.put("model", map);
	        temp.process(root, writer);
	        writer.flush();
			result = writer.toString();			
		} catch (Exception e) {
			e.printStackTrace();
			result = "";
		}
		return result;
	}
}
